<?php
namespace app\common\service;
use EasyWeChat\MiniApp\Application;
use EasyWeChat\Kernel\Exceptions\HttpException;
use think\facade\Config;
use think\facade\Log;
class WeChatService
{
    protected $app;

    private $config;

    public function __construct()
    {
        $this->config = $this->getConfig();
        $this->app = new Application($this->config);
    }

    /**
     * @notes 配置
     * @return array
     * @throws \Exception
     */
    protected  function getConfig()
    {
        $config = WeChatConfigService::getMnpConfig();
        if (empty($config['app_id']) || empty($config['secret'])) {
            throw new \Exception('请先设置小程序配置');
        }
        return $config;
    }


    /**
     * @notes 小程序-根据code获取微信信息
     * @param string $code
     * @return array
     * @throws HttpException
     */
    public  function getMnpResByCode(string $code): array
    {
        // 参数基础校验
        if (empty(trim($code))) {
            // 返回错误信息数组而不是抛出异常
            return ['error' => '登录凭证(code)不能为空'];
        }

        try {
            $utils = $this->app->getUtils();
            $response = $utils->codeToSession($code);

            // 检查微信返回的错误信息
            if (isset($response['errcode']) && $response['errcode'] !== 0) {
                $errorMessage = $this->getWeChatErrorMessage($response['errcode']);
                Log::error('微信登录失败', [
                    'timestamp' => date('Y-m-d H:i:s'),
                    'errcode' => $response['errcode'],
                    'errmsg' => $response['errmsg'] ?? '',
                    'appid' => $this->app->getAccount()->getAppId()
                ]);

                // 返回错误信息而不是抛出异常
                return ['error' => sprintf('微信登录失败：%s', $errorMessage)];
            }

            if (!isset($response['openid']) || empty($response['openid'])) {
                // 返回错误信息而不是抛出异常
                return ['error' => '获取openID失败'];
            }

            return $response;
        } catch (\Exception $e) {
            // 记录日志并返回错误信息
            Log::error('微信登录异常', [
                'timestamp' => date('Y-m-d H:i:s'),
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            return ['error' => '微信登录服务暂时不可用，请稍后重试'];
        }
    }

    /**
     * 获取微信错误码对应的友好提示信息
     * @param int $errcode
     * @return string
     */
    private function getWeChatErrorMessage(int $errcode): string
    {
        $errorMessages = [
            40013 => '小程序AppID无效，请检查配置',
            40029 => '登录凭证(code)无效',
            40125 => '小程序Secret无效',
            40163 => '登录凭证已过期',
            45011 => '接口调用过于频繁，请稍后重试',
            -1 => '系统繁忙，请稍后重试'
        ];

        return $errorMessages[$errcode] ?? '未知错误(' . $errcode . ')';
    }


    /**
     * @notes 获取手机号
     * @param string $code
     */
    public  function getUserPhoneNumber(string $code)
    {
        if (empty(trim($code))) {
            // 返回错误信息而不是抛出异常
            return ['error' => '手机号授权码不能为空'];
        }

        try {
            $response = $this->app->getClient()->postJson('wxa/business/getuserphonenumber', [
                'code' => $code,
            ]);

            // 简单校验响应是否成功
            $data = json_decode((string)$response->getBody(), true);
            if (isset($data['errcode']) && $data['errcode'] !== 0) {
                Log::error('获取手机号失败', [
                    'timestamp' => date('Y-m-d H:i:s'),
                    'errcode' => $data['errcode'],
                    'errmsg' => $data['errmsg'] ?? ''
                ]);
                // 可以选择返回错误信息或原始响应
                return ['error' => $data['errmsg'] ?? '获取手机号失败', 'data' => $data];
            }

            return $response;
        } catch (\Exception $e) {
            Log::error('获取手机号异常', [
                'timestamp' => date('Y-m-d H:i:s'),
                'message' => $e->getMessage()
            ]);
            return ['error' => '获取手机号服务暂时不可用'];
        }
    }

}
